from typing import List  # 导入类型提示模块
from fastapi import Depends, FastAPI, HTTPException, Request, Response  # 导入FastAPI相关模块
from sqlalchemy.orm import Session  # 导入SQLAlchemy会话类
from . import crud, models, schemas  # 导入本地CRUD操作、模型和模式定义
from .database import SessionLocal, engine  # 导入数据库会话和引擎

# 使用中间件代替数据库会话 “中间件”基本功能是一个为每个请求执行的函数在请求之前进行执行相应的代码，以及在请求执行之后执行相应的代码。
# 我们将添加中间件（只是一个函数）将为每个请求创建一个新的 SQLAlchemySessionLocal，将其添加到请求中，然后在请求完成后关闭它。

# 创建所有表结构
models.Base.metadata.create_all(bind=engine)

# 初始化FastAPI应用
app = FastAPI()

# 中间件：管理数据库会话
@app.middleware("http")
async def db_session_middleware(request: Request, call_next):
    """
    管理每个请求的数据库会话。

    :param request: 请求对象
    :param call_next: 下一个中间件的调用
    :return: 响应对象
    """
    response = Response("Internal server error", status_code=500)
    try:
        request.state.db = SessionLocal()  # 创建数据库会话
        response = await call_next(request)  # 处理下一个中间件
    finally:
        request.state.db.close()  # 关闭数据库会话
    return response

# 依赖项
def get_db(request: Request):
    """
    获取数据库会话依赖。

    :param request: 请求对象
    :return: 数据库会话对象
    """
    return request.state.db

# 创建新用户
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
    """
    创建新用户。

    :param user: 新用户的创建信息
    :param db: SQLAlchemy会话对象
    :return: 创建的用户对象
    """
    db_user = crud.get_user_by_email(db, email=user.email)
    if db_user:
        raise HTTPException(status_code=400, detail="Email already registered")
    return crud.create_user(db=db, user=user)

# 获取所有用户
@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    """
    获取所有用户信息，并支持分页。

    :param skip: 跳过的记录数
    :param limit: 每页显示的记录数
    :param db: SQLAlchemy会话对象
    :return: 用户列表
    """
    users = crud.get_users(db, skip=skip, limit=limit)
    return users

# 获取单个用户
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
    """
    获取单个用户信息。

    :param user_id: 用户ID
    :param db: SQLAlchemy会话对象
    :return: 用户对象或抛出HTTP异常
    """
    db_user = crud.get_user(db, user_id=user_id)
    if db_user is None:
        raise HTTPException(status_code=404, detail="User not found")
    return db_user

# 创建用户项目
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)):
    """
    创建新项目并关联到指定用户。

    :param user_id: 用户ID
    :param item: 新项目的创建信息
    :param db: SQLAlchemy会话对象
    :return: 创建的项目对象
    """
    return crud.create_user_item(db=db, item=item, user_id=user_id)

# 获取所有项目
@app.get("/items/", response_model=List[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    """
    获取所有项目信息，并支持分页。

    :param skip: 跳过的记录数
    :param limit: 每页显示的记录数
    :param db: SQLAlchemy会话对象
    :return: 项目列表
    """
    items = crud.get_items(db, skip=skip, limit=limit)
    return items
